home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Tools / idle / ScriptBinding.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  4.8 KB  |  155 lines

  1. """Extension to execute code outside the Python shell window.
  2.  
  3. This adds two commands (to the Edit menu, until there's a separate
  4. Python menu):
  5.  
  6. - Run module (F5) is equivalent to either import or reload of the
  7. current module.  The window must have been saved previously. The
  8. module only gets added to sys.modules, it doesn't get added to
  9. anyone's namespace; you can import it in the shell if you need to.  If
  10. this generates any output to sys.stdout or sys.stderr, a new output
  11. window is created to display that output. The two streams are
  12. distinguished by their text color.
  13.  
  14. - Debug module (Control-F5) does the same but executes the module's
  15. code in the debugger.
  16.  
  17. When an unhandled exception occurs in Run module, the stack viewer is
  18. popped up.  This is not done in Debug module, because you've already
  19. had an opportunity to view the stack.  In either case, the variables
  20. sys.last_type, sys.last_value, sys.last_traceback are set to the
  21. exception info.
  22.  
  23. """
  24.  
  25. import sys
  26. import os
  27. import imp
  28. import linecache
  29. import traceback
  30. import tkMessageBox
  31. from OutputWindow import OutputWindow
  32.  
  33. # XXX These helper classes are more generally usable!
  34.  
  35. class OnDemandOutputWindow:
  36.  
  37.     tagdefs = {
  38.         "stdout":  {"foreground": "blue"},
  39.         "stderr":  {"foreground": "#007700"},
  40.     }   
  41.     
  42.     def __init__(self, flist):
  43.         self.flist = flist
  44.         self.owin = None
  45.     
  46.     def write(self, s, tags, mark):
  47.         if not self.owin:
  48.             self.setup()
  49.         self.owin.write(s, tags, mark)
  50.     
  51.     def setup(self):
  52.         self.owin = owin = OutputWindow(self.flist)
  53.         text = owin.text
  54.         for tag, cnf in self.tagdefs.items():
  55.             if cnf:
  56.                 apply(text.tag_configure, (tag,), cnf)
  57.         text.tag_raise('sel')
  58.         self.write = self.owin.write
  59.  
  60. class PseudoFile:
  61.  
  62.     def __init__(self, owin, tags, mark="end"):
  63.         self.owin = owin
  64.         self.tags = tags
  65.         self.mark = mark
  66.  
  67.     def write(self, s):
  68.         self.owin.write(s, self.tags, self.mark)
  69.  
  70.     def writelines(self, l):
  71.         map(self.write, l)
  72.  
  73.     def flush(self):
  74.         pass
  75.  
  76.  
  77. class ScriptBinding:
  78.     
  79.     keydefs = {
  80.         '<<run-module>>': ['<F5>'],
  81.         '<<debug-module>>': ['<Control-F5>'],
  82.     }
  83.     
  84.     menudefs = [
  85.         ('edit', [None,
  86.                   ('Run module', '<<run-module>>'),
  87.                   ('Debug module', '<<debug-module>>'),
  88.                  ]
  89.         ),
  90.     ]
  91.  
  92.     def __init__(self, editwin):
  93.         self.editwin = editwin
  94.         # Provide instance variables referenced by Debugger
  95.         # XXX This should be done differently
  96.         self.flist = self.editwin.flist
  97.         self.root = self.flist.root
  98.  
  99.     def run_module_event(self, event, debugger=None):
  100.         if not self.editwin.get_saved():
  101.             tkMessageBox.showerror("Not saved",
  102.                                    "Please save first!",
  103.                                    master=self.editwin.text)
  104.             self.editwin.text.focus_set()
  105.             return
  106.         filename = self.editwin.io.filename
  107.         if not filename:
  108.             tkMessageBox.showerror("No file name",
  109.                                    "This window has no file name",
  110.                                    master=self.editwin.text)
  111.             self.editwin.text.focus_set()
  112.             return
  113.         modname, ext = os.path.splitext(os.path.basename(filename))
  114.         if sys.modules.has_key(modname):
  115.             mod = sys.modules[modname]
  116.         else:
  117.             mod = imp.new_module(modname)
  118.             sys.modules[modname] = mod
  119.         mod.__file__ = filename
  120.         saveout = sys.stdout
  121.         saveerr = sys.stderr
  122.         owin = OnDemandOutputWindow(self.editwin.flist)
  123.         try:
  124.             sys.stderr = PseudoFile(owin, "stderr")
  125.             try:
  126.                 sys.stdout = PseudoFile(owin, "stdout")
  127.                 try:
  128.                     if debugger:
  129.                         debugger.run("execfile(%s)" % `filename`, mod.__dict__)
  130.                     else:
  131.                         execfile(filename, mod.__dict__)
  132.                 except:
  133.                     (sys.last_type, sys.last_value,
  134.                      sys.last_traceback) = sys.exc_info()
  135.                     linecache.checkcache()
  136.                     traceback.print_exc()
  137.                     if not debugger and \
  138.                        self.editwin.getvar("<<toggle-jit-stack-viewer>>"):
  139.                         from StackViewer import StackBrowser
  140.                         sv = StackBrowser(self.root, self.flist)
  141.             finally:
  142.                 sys.stdout = saveout
  143.         finally:
  144.             sys.stderr = saveerr
  145.  
  146.     def debug_module_event(self, event):
  147.         import Debugger
  148.         debugger = Debugger.Debugger(self)
  149.         self.run_module_event(event, debugger)
  150.  
  151.     def close_debugger(self):
  152.         # Method called by Debugger
  153.         # XXX This should be done differently
  154.         pass
  155.